Generated on Fri Jan 28 2022 04:43:06 for Gecode by doxygen 1.8.13
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, IntPropLevel ipl,
73  long long int m, long long int& d) const;
75  int fill(Home home, IntPropLevel ipl,
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  */
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 != NULL) && l->decrement())
127  delete l;
128  if ((r != NULL) && 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,ipl,ti,tb,1,d);
151  Int::Limits::check(d,"MiniModel::LinIntExpr");
152  return static_cast<int>(d);
153  }
154 
155  void
157  if (home.failed()) return;
158  Region r;
159  if (n->n_bool == 0) {
160  // Only integer variables
161  if (n->t==NT_ADD && n->l == NULL && n->r->t==NT_NONLIN) {
162  n->r->sum.ne->post(home,irt,-n->c,ipl);
163  } else if (n->t==NT_SUB && n->r->t==NT_NONLIN && n->l==NULL) {
164  switch (irt) {
165  case IRT_LQ: irt=IRT_GQ; break;
166  case IRT_LE: irt=IRT_GR; break;
167  case IRT_GQ: irt=IRT_LQ; break;
168  case IRT_GR: irt=IRT_LE; break;
169  default: break;
170  }
171  n->r->sum.ne->post(home,irt,n->c,ipl);
172  } else if (irt==IRT_EQ &&
173  n->t==NT_SUB && n->r->t==NT_NONLIN &&
174  n->l != NULL && n->l->t==NT_VAR_INT
175  && n->l->a==1) {
176  (void) n->r->sum.ne->post(home,&n->l->x_int,ipl);
177  } else if (irt==IRT_EQ &&
178  n->t==NT_SUB && n->r->t==NT_VAR_INT &&
179  n->l != NULL && n->l->t==NT_NONLIN
180  && n->r->a==1) {
181  (void) n->l->sum.ne->post(home,&n->r->x_int,ipl);
182  } else {
185  int c = n->fill(home,ipl,its,NULL);
186  Int::Linear::post(home, its, n->n_int, irt, -c, ipl);
187  }
188  } else if (n->n_int == 0) {
189  // Only Boolean variables
192  int c = n->fill(home,ipl,NULL,bts);
193  Int::Linear::post(home, bts, n->n_bool, irt, -c, ipl);
194  } else if (n->n_bool == 1) {
195  // Integer variables and only one Boolean variable
200  int c = n->fill(home,ipl,its,bts);
201  IntVar x(home,0,1);
202  channel(home,bts[0].x,x);
203  its[n->n_int].x = x;
204  its[n->n_int].a = bts[0].a;
205  Int::Linear::post(home, its, n->n_int+1, irt, -c, ipl);
206  } else {
207  // Both integer and Boolean variables
212  int c = n->fill(home,ipl,its,bts);
213  int min, max;
214  Int::Linear::estimate(&bts[0],n->n_bool,0,min,max);
215  IntVar x(home,min,max);
216  its[n->n_int].x = x; its[n->n_int].a = 1;
217  Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0, ipl);
218  Int::Linear::post(home, its, n->n_int+1, irt, -c, ipl);
219  }
220  }
221 
222  void
224  IntPropLevel ipl) const {
225  if (home.failed()) return;
226  Region r;
227  if (n->n_bool == 0) {
228  // Only integer variables
229  if (n->t==NT_ADD && n->l==NULL && n->r->t==NT_NONLIN) {
230  n->r->sum.ne->post(home,irt,-n->c,b,ipl);
231  } else if (n->t==NT_SUB && n->l==NULL && n->r->t==NT_NONLIN) {
232  switch (irt) {
233  case IRT_LQ: irt=IRT_GQ; break;
234  case IRT_LE: irt=IRT_GR; break;
235  case IRT_GQ: irt=IRT_LQ; break;
236  case IRT_GR: irt=IRT_LE; break;
237  default: break;
238  }
239  n->r->sum.ne->post(home,irt,n->c,b,ipl);
240  } else {
243  int c = n->fill(home,ipl,its,NULL);
244  Int::Linear::post(home, its, n->n_int, irt, -c, b, ipl);
245  }
246  } else if (n->n_int == 0) {
247  // Only Boolean variables
250  int c = n->fill(home,ipl,NULL,bts);
251  Int::Linear::post(home, bts, n->n_bool, irt, -c, b, ipl);
252  } else if (n->n_bool == 1) {
253  // Integer variables and only one Boolean variable
258  int c = n->fill(home,ipl,its,bts);
259  IntVar x(home,0,1);
260  channel(home,bts[0].x,x);
261  its[n->n_int].x = x;
262  its[n->n_int].a = bts[0].a;
263  Int::Linear::post(home, its, n->n_int+1, irt, -c, b, ipl);
264  } else {
265  // Both integer and Boolean variables
270  int c = n->fill(home,ipl,its,bts);
271  int min, max;
272  Int::Linear::estimate(&bts[0],n->n_bool,0,min,max);
273  IntVar x(home,min,max);
274  its[n->n_int].x = x; its[n->n_int].a = 1;
275  Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0, ipl);
276  Int::Linear::post(home, its, n->n_int+1, irt, -c, b, ipl);
277  }
278  }
279 
280  IntVar
281  LinIntExpr::post(Home home, IntPropLevel ipl) const {
282  if (home.failed()) return IntVar(home,0,0);
283  Region r;
284  if (n->n_bool == 0) {
285  // Only integer variables
288  int c = n->fill(home,ipl,its,NULL);
289  if ((n->n_int == 1) && (c == 0) && (its[0].a == 1))
290  return its[0].x;
291  int min, max;
292  Int::Linear::estimate(&its[0],n->n_int,c,min,max);
293  IntVar x(home, min, max);
294  its[n->n_int].x = x; its[n->n_int].a = -1;
295  Int::Linear::post(home, its, n->n_int+1, IRT_EQ, -c, ipl);
296  return x;
297  } else if (n->n_int == 0) {
298  // Only Boolean variables
301  int c = n->fill(home,ipl,NULL,bts);
302  int min, max;
303  Int::Linear::estimate(&bts[0],n->n_bool,c,min,max);
304  IntVar x(home, min, max);
305  Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, -c, ipl);
306  return x;
307  } else if (n->n_bool == 1) {
308  // Integer variables and single Boolean variable
313  int c = n->fill(home,ipl,its,bts);
314  IntVar x(home, 0, 1);
315  channel(home, x, bts[0].x);
316  its[n->n_int].x = x; its[n->n_int].a = bts[0].a;
317  int y_min, y_max;
318  Int::Linear::estimate(&its[0],n->n_int+1,c,y_min,y_max);
319  IntVar y(home, y_min, y_max);
320  its[n->n_int+1].x = y; its[n->n_int+1].a = -1;
321  Int::Linear::post(home, its, n->n_int+2, IRT_EQ, -c, ipl);
322  return y;
323  } else {
324  // Both integer and Boolean variables
329  int c = n->fill(home,ipl,its,bts);
330  int x_min, x_max;
331  Int::Linear::estimate(&bts[0],n->n_bool,0,x_min,x_max);
332  IntVar x(home, x_min, x_max);
333  Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0, ipl);
334  its[n->n_int].x = x; its[n->n_int].a = 1;
335  int y_min, y_max;
336  Int::Linear::estimate(&its[0],n->n_int+1,c,y_min,y_max);
337  IntVar y(home, y_min, y_max);
338  its[n->n_int+1].x = y; its[n->n_int+1].a = -1;
339  Int::Linear::post(home, its, n->n_int+2, IRT_EQ, -c, ipl);
340  return y;
341  }
342  }
343 
345  LinIntExpr::nle(void) const {
346  return n->t == NT_NONLIN ? n->sum.ne : NULL;
347  }
348 
350  n(new Node) {
351  n->n_int = n->n_bool = 0;
352  n->t = NT_VAR_INT;
353  n->l = n->r = NULL;
354  n->a = 0;
355  }
356 
358  n(new Node) {
359  n->n_int = n->n_bool = 0;
360  n->t = NT_CONST;
361  n->l = n->r = NULL;
362  n->a = 0;
363  Int::Limits::check(c,"MiniModel::LinIntExpr");
364  n->c = c;
365  }
366 
368  n(new Node) {
369  n->n_int = 1;
370  n->n_bool = 0;
371  n->t = NT_VAR_INT;
372  n->l = n->r = NULL;
373  n->a = a;
374  n->x_int = x;
375  }
376 
378  n(new Node) {
379  n->n_int = 0;
380  n->n_bool = 1;
381  n->t = NT_VAR_BOOL;
382  n->l = n->r = NULL;
383  n->a = a;
384  n->x_bool = x;
385  }
386 
388  n(new Node) {
389  n->n_int = x.size();
390  n->n_bool = 0;
391  n->t = NT_SUM_INT;
392  n->l = n->r = NULL;
393  if (x.size() > 0) {
395  for (int i=x.size(); i--; ) {
396  n->sum.ti[i].x = x[i];
397  n->sum.ti[i].a = 1;
398  }
399  }
400  }
401 
403  n(new Node) {
404  if (a.size() != x.size())
405  throw Int::ArgumentSizeMismatch("MiniModel::LinIntExpr");
406  n->n_int = x.size();
407  n->n_bool = 0;
408  n->t = NT_SUM_INT;
409  n->l = n->r = NULL;
410  if (x.size() > 0) {
412  for (int i=x.size(); i--; ) {
413  n->sum.ti[i].x = x[i];
414  n->sum.ti[i].a = a[i];
415  }
416  }
417  }
418 
420  n(new Node) {
421  n->n_int = 0;
422  n->n_bool = x.size();
423  n->t = NT_SUM_BOOL;
424  n->l = n->r = NULL;
425  if (x.size() > 0) {
427  for (int i=x.size(); i--; ) {
428  n->sum.tb[i].x = x[i];
429  n->sum.tb[i].a = 1;
430  }
431  }
432  }
433 
435  n(new Node) {
436  if (a.size() != x.size())
437  throw Int::ArgumentSizeMismatch("MiniModel::LinIntExpr");
438  n->n_int = 0;
439  n->n_bool = x.size();
440  n->t = NT_SUM_BOOL;
441  n->l = n->r = NULL;
442  if (x.size() > 0) {
444  for (int i=x.size(); i--; ) {
445  n->sum.tb[i].x = x[i];
446  n->sum.tb[i].a = a[i];
447  }
448  }
449  }
450 
452  n(new Node) {
453  n->n_int = e0.n->n_int + e1.n->n_int;
454  n->n_bool = e0.n->n_bool + e1.n->n_bool;
455  n->t = t;
456  n->l = e0.n; n->l->use++;
457  n->r = e1.n; n->r->use++;
458  }
459 
461  n(new Node) {
462  n->n_int = e.n->n_int;
463  n->n_bool = e.n->n_bool;
464  n->t = t;
465  n->l = NULL;
466  n->r = e.n; n->r->use++;
467  n->c = c;
468  }
469 
471  n(new Node) {
472  n->n_int = e.n->n_int;
473  n->n_bool = e.n->n_bool;
474  n->t = NT_MUL;
475  n->l = e.n; n->l->use++;
476  n->r = NULL;
477  n->a = a;
478  }
479 
481  n(new Node) {
482  n->n_int = 1;
483  n->n_bool = 0;
484  n->t = NT_NONLIN;
485  n->l = n->r = NULL;
486  n->a = 0;
487  n->sum.ne = e;
488  }
489 
490  const LinIntExpr&
492  if (this != &e) {
493  if (n->decrement())
494  delete n;
495  n = e.n; n->use++;
496  }
497  return *this;
498  }
499 
501  if (n->decrement())
502  delete n;
503  }
504 
505 
506  void
510  long long int m, long long int& d) const {
511  switch (this->t) {
512  case NT_CONST:
513  Int::Limits::check(m*c,"MiniModel::LinIntExpr");
514  d += m*c;
515  break;
516  case NT_VAR_INT:
517  Int::Limits::check(m*a,"MiniModel::LinIntExpr");
518  ti->a=static_cast<int>(m*a); ti->x=x_int; ti++;
519  break;
520  case NT_NONLIN:
521  ti->a=static_cast<int>(m); ti->x=sum.ne->post(home, NULL, ipl); ti++;
522  break;
523  case NT_VAR_BOOL:
524  Int::Limits::check(m*a,"MiniModel::LinIntExpr");
525  tb->a=static_cast<int>(m*a); tb->x=x_bool; tb++;
526  break;
527  case NT_SUM_INT:
528  for (int i=n_int; i--; ) {
529  Int::Limits::check(m*sum.ti[i].a,"MiniModel::LinIntExpr");
530  ti[i].x = sum.ti[i].x; ti[i].a = static_cast<int>(m*sum.ti[i].a);
531  }
532  ti += n_int;
533  break;
534  case NT_SUM_BOOL:
535  for (int i=n_bool; i--; ) {
536  Int::Limits::check(m*sum.tb[i].a,"MiniModel::LinIntExpr");
537  tb[i].x = sum.tb[i].x; tb[i].a = static_cast<int>(m*sum.tb[i].a);
538  }
539  tb += n_bool;
540  break;
541  case NT_ADD:
542  if (l == NULL) {
543  Int::Limits::check(m*c,"MiniModel::LinIntExpr");
544  d += m*c;
545  } else {
546  l->fill(home,ipl,ti,tb,m,d);
547  }
548  r->fill(home,ipl,ti,tb,m,d);
549  break;
550  case NT_SUB:
551  if (l == NULL) {
552  Int::Limits::check(m*c,"MiniModel::LinIntExpr");
553  d += m*c;
554  } else {
555  l->fill(home,ipl,ti,tb,m,d);
556  }
557  r->fill(home,ipl,ti,tb,-m,d);
558  break;
559  case NT_MUL:
560  Int::Limits::check(m*a,"MiniModel::LinIntExpr");
561  l->fill(home,ipl,ti,tb,m*a,d);
562  break;
563  default:
564  GECODE_NEVER;
565  }
566  }
567 
568 
569  /*
570  * Operators
571  *
572  */
573  LinIntExpr
574  operator +(int c, const IntVar& x) {
575  if (x.assigned() &&
576  Int::Limits::valid(static_cast<long long int>(c)+x.val()))
577  return LinIntExpr(c+x.val());
578  else
579  return LinIntExpr(x,LinIntExpr::NT_ADD,c);
580  }
581  LinIntExpr
582  operator +(int c, const BoolVar& x) {
583  if (x.assigned() &&
584  Int::Limits::valid(static_cast<long long int>(c)+x.val()))
585  return LinIntExpr(c+x.val());
586  else
587  return LinIntExpr(x,LinIntExpr::NT_ADD,c);
588  }
589  LinIntExpr
590  operator +(int c, const LinIntExpr& e) {
591  return LinIntExpr(e,LinIntExpr::NT_ADD,c);
592  }
593  LinIntExpr
594  operator +(const IntVar& x, int c) {
595  if (x.assigned() &&
596  Int::Limits::valid(static_cast<long long int>(c)+x.val()))
597  return LinIntExpr(c+x.val());
598  else
599  return LinIntExpr(x,LinIntExpr::NT_ADD,c);
600  }
601  LinIntExpr
602  operator +(const BoolVar& x, int c) {
603  if (x.assigned() &&
604  Int::Limits::valid(static_cast<long long int>(c)+x.val()))
605  return LinIntExpr(c+x.val());
606  else
607  return LinIntExpr(x,LinIntExpr::NT_ADD,c);
608  }
609  LinIntExpr
610  operator +(const LinIntExpr& e, int c) {
611  return LinIntExpr(e,LinIntExpr::NT_ADD,c);
612  }
613  LinIntExpr
614  operator +(const IntVar& x, const IntVar& y) {
615  if (x.assigned())
616  return x.val() + y;
617  else if (y.assigned())
618  return x + y.val();
619  else
620  return LinIntExpr(x,LinIntExpr::NT_ADD,y);
621  }
622  LinIntExpr
623  operator +(const IntVar& x, const BoolVar& y) {
624  if (x.assigned())
625  return x.val() + y;
626  else if (y.assigned())
627  return x + y.val();
628  else
629  return LinIntExpr(x,LinIntExpr::NT_ADD,y);
630  }
631  LinIntExpr
632  operator +(const BoolVar& x, const IntVar& y) {
633  if (x.assigned())
634  return x.val() + y;
635  else if (y.assigned())
636  return x + y.val();
637  else
638  return LinIntExpr(x,LinIntExpr::NT_ADD,y);
639  }
640  LinIntExpr
641  operator +(const BoolVar& x, const BoolVar& y) {
642  if (x.assigned())
643  return x.val() + y;
644  else if (y.assigned())
645  return x + y.val();
646  else
647  return LinIntExpr(x,LinIntExpr::NT_ADD,y);
648  }
649  LinIntExpr
650  operator +(const IntVar& x, const LinIntExpr& e) {
651  if (x.assigned())
652  return x.val() + e;
653  else
654  return LinIntExpr(x,LinIntExpr::NT_ADD,e);
655  }
656  LinIntExpr
657  operator +(const BoolVar& x, const LinIntExpr& e) {
658  if (x.assigned())
659  return x.val() + e;
660  else
661  return LinIntExpr(x,LinIntExpr::NT_ADD,e);
662  }
663  LinIntExpr
664  operator +(const LinIntExpr& e, const IntVar& x) {
665  if (x.assigned())
666  return e + x.val();
667  else
668  return LinIntExpr(e,LinIntExpr::NT_ADD,x);
669  }
670  LinIntExpr
671  operator +(const LinIntExpr& e, const BoolVar& x) {
672  if (x.assigned())
673  return e + x.val();
674  else
675  return LinIntExpr(e,LinIntExpr::NT_ADD,x);
676  }
677  LinIntExpr
678  operator +(const LinIntExpr& e1, const LinIntExpr& e2) {
679  return LinIntExpr(e1,LinIntExpr::NT_ADD,e2);
680  }
681 
682  LinIntExpr
683  operator -(int c, const IntVar& x) {
684  if (x.assigned() &&
685  Int::Limits::valid(static_cast<long long int>(c)-x.val()))
686  return LinIntExpr(c-x.val());
687  else
688  return LinIntExpr(x,LinIntExpr::NT_SUB,c);
689  }
690  LinIntExpr
691  operator -(int c, const BoolVar& x) {
692  if (x.assigned() &&
693  Int::Limits::valid(static_cast<long long int>(c)-x.val()))
694  return LinIntExpr(c-x.val());
695  else
696  return LinIntExpr(x,LinIntExpr::NT_SUB,c);
697  }
698  LinIntExpr
699  operator -(int c, const LinIntExpr& e) {
700  return LinIntExpr(e,LinIntExpr::NT_SUB,c);
701  }
702  LinIntExpr
703  operator -(const IntVar& x, int c) {
704  if (x.assigned() &&
705  Int::Limits::valid(x.val()-static_cast<long long int>(c)))
706  return LinIntExpr(x.val()-c);
707  else
708  return LinIntExpr(x,LinIntExpr::NT_ADD,-c);
709  }
710  LinIntExpr
711  operator -(const BoolVar& x, int c) {
712  if (x.assigned() &&
713  Int::Limits::valid(x.val()-static_cast<long long int>(c)))
714  return LinIntExpr(x.val()-c);
715  else
716  return LinIntExpr(x,LinIntExpr::NT_ADD,-c);
717  }
718  LinIntExpr
719  operator -(const LinIntExpr& e, int c) {
720  return LinIntExpr(e,LinIntExpr::NT_ADD,-c);
721  }
722  LinIntExpr
723  operator -(const IntVar& x, const IntVar& y) {
724  if (x.assigned())
725  return x.val() - y;
726  else if (y.assigned())
727  return x - y.val();
728  else
729  return LinIntExpr(x,LinIntExpr::NT_SUB,y);
730  }
731  LinIntExpr
732  operator -(const IntVar& x, const BoolVar& y) {
733  if (x.assigned())
734  return x.val() - y;
735  else if (y.assigned())
736  return x - y.val();
737  else
738  return LinIntExpr(x,LinIntExpr::NT_SUB,y);
739  }
740  LinIntExpr
741  operator -(const BoolVar& x, const IntVar& y) {
742  if (x.assigned())
743  return x.val() - y;
744  else if (y.assigned())
745  return x - y.val();
746  else
747  return LinIntExpr(x,LinIntExpr::NT_SUB,y);
748  }
749  LinIntExpr
750  operator -(const BoolVar& x, const BoolVar& y) {
751  if (x.assigned())
752  return x.val() - y;
753  else if (y.assigned())
754  return x - y.val();
755  else
756  return LinIntExpr(x,LinIntExpr::NT_SUB,y);
757  }
758  LinIntExpr
759  operator -(const IntVar& x, const LinIntExpr& e) {
760  if (x.assigned())
761  return x.val() - e;
762  else
763  return LinIntExpr(x,LinIntExpr::NT_SUB,e);
764  }
765  LinIntExpr
766  operator -(const BoolVar& x, const LinIntExpr& e) {
767  if (x.assigned())
768  return x.val() - e;
769  else
770  return LinIntExpr(x,LinIntExpr::NT_SUB,e);
771  }
772  LinIntExpr
773  operator -(const LinIntExpr& e, const IntVar& x) {
774  if (x.assigned())
775  return e - x.val();
776  else
777  return LinIntExpr(e,LinIntExpr::NT_SUB,x);
778  }
779  LinIntExpr
780  operator -(const LinIntExpr& e, const BoolVar& x) {
781  if (x.assigned())
782  return e - x.val();
783  else
784  return LinIntExpr(e,LinIntExpr::NT_SUB,x);
785  }
786  LinIntExpr
787  operator -(const LinIntExpr& e1, const LinIntExpr& e2) {
788  return LinIntExpr(e1,LinIntExpr::NT_SUB,e2);
789  }
790 
791  LinIntExpr
792  operator -(const IntVar& x) {
793  if (x.assigned())
794  return LinIntExpr(-x.val());
795  else
796  return LinIntExpr(x,LinIntExpr::NT_SUB,0);
797  }
798  LinIntExpr
799  operator -(const BoolVar& x) {
800  if (x.assigned())
801  return LinIntExpr(-x.val());
802  else
803  return LinIntExpr(x,LinIntExpr::NT_SUB,0);
804  }
805  LinIntExpr
806  operator -(const LinIntExpr& e) {
807  return LinIntExpr(e,LinIntExpr::NT_SUB,0);
808  }
809 
810  LinIntExpr
811  operator *(int a, const IntVar& x) {
812  if (a == 0)
813  return LinIntExpr(0);
814  else if (x.assigned() &&
815  Int::Limits::valid(static_cast<long long int>(a)*x.val()))
816  return LinIntExpr(a*x.val());
817  else
818  return LinIntExpr(x,a);
819  }
820  LinIntExpr
821  operator *(int a, const BoolVar& x) {
822  if (a == 0)
823  return LinIntExpr(0);
824  else if (x.assigned() &&
825  Int::Limits::valid(static_cast<long long int>(a)*x.val()))
826  return LinIntExpr(a*x.val());
827  else
828  return LinIntExpr(x,a);
829  }
830  LinIntExpr
831  operator *(const IntVar& x, int a) {
832  if (a == 0)
833  return LinIntExpr(0);
834  else if (x.assigned() &&
835  Int::Limits::valid(static_cast<long long int>(a)*x.val()))
836  return LinIntExpr(a*x.val());
837  else
838  return LinIntExpr(x,a);
839  }
840  LinIntExpr
841  operator *(const BoolVar& x, int a) {
842  if (a == 0)
843  return LinIntExpr(0);
844  else if (x.assigned() &&
845  Int::Limits::valid(static_cast<long long int>(a)*x.val()))
846  return LinIntExpr(a*x.val());
847  else
848  return LinIntExpr(x,a);
849  }
850  LinIntExpr
851  operator *(const LinIntExpr& e, int a) {
852  if (a == 0)
853  return LinIntExpr(0);
854  else
855  return LinIntExpr(a,e);
856  }
857  LinIntExpr
858  operator *(int a, const LinIntExpr& e) {
859  if (a == 0)
860  return LinIntExpr(0);
861  else
862  return LinIntExpr(a,e);
863  }
864 
865  LinIntExpr
866  sum(const IntVarArgs& x) {
867  return LinIntExpr(x);
868  }
869  LinIntExpr
870  sum(const IntArgs& a, const IntVarArgs& x) {
871  return LinIntExpr(a,x);
872  }
873  LinIntExpr
874  sum(const BoolVarArgs& x) {
875  return LinIntExpr(x);
876  }
877  LinIntExpr
878  sum(const IntArgs& a, const BoolVarArgs& x) {
879  return LinIntExpr(a,x);
880  }
881  LinIntExpr
883  const Slice<IntArgs>::ArgsType & args = slice;
884  return sum(args);
885  }
886  LinIntExpr
887  sum(const Matrix<IntArgs>& matrix) {
888  const Matrix<IntArgs>::ArgsType & args = matrix.get_array();
889  return sum(args);
890  }
891  LinIntExpr
892  sum(const IntArgs& args) {
893  int sum = 0;
894  for (int i = 0; i<args.size(); i++)
895  sum += args[i];
896  return LinIntExpr(sum);
897  }
898 
899 
900  IntVar
901  expr(Home home, const LinIntExpr& e, IntPropLevel ipl) {
902  PostInfo pi(home);
903  if (!home.failed())
904  return e.post(home,ipl);
906  return x;
907  }
908 
909 }
910 
911 // STATISTICS: minimodel-any
FloatVal operator-(const FloatVal &x)
Definition: val.hpp:168
IntVar x_int
Integer variable (potentially)
Definition: int-expr.cpp:64
NodeType t
Type of node.
Definition: bool-expr.cpp:230
NNF * l
Left subtree.
Definition: bool-expr.cpp:240
NodeType t
Type of expression.
Definition: int-expr.cpp:49
int size(void) const
Return size of array (number of elements)
Definition: array.hpp:1569
void channel(Home home, FloatVar x0, IntVar x1)
Post propagator for channeling a float and an integer variable .
Definition: channel.cpp:41
void rfree(void *p)
Free memory block starting at p.
Definition: heap.hpp:371
int a
Coefficient.
Definition: linear.hh:1339
T * alloc(long unsigned int n)
Allocate block of n objects of type T from region.
Definition: region.hpp:386
unsigned int use
Nodes are reference counted.
Definition: int-expr.cpp:43
Linear term with Boolean variable.
Definition: minimodel.hh:153
void max(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition: arithmetic.cpp:49
bool assigned(void) const
Test whether view is assigned.
Definition: var.hpp:111
Less or equal ( )
Definition: int.hh:928
Int::Linear::Term< Int::BoolView > * tb
Bool views and coefficients.
Definition: int-expr.cpp:57
Base class for non-linear expressions over integer variables.
Definition: minimodel.hh:109
void * ralloc(size_t s)
Allocate s bytes from heap.
Definition: heap.hpp:357
Addition of linear terms.
Definition: minimodel.hh:157
Node * l
Subexpressions.
Definition: int-expr.cpp:51
Multiplication by coefficient.
Definition: minimodel.hh:159
Handle to region.
Definition: region.hpp:55
Greater ( )
Definition: int.hh:931
#define forceinline
Definition: config.hpp:185
Linear term with integer variable.
Definition: minimodel.hh:152
const int max
Largest allowed integer value.
Definition: int.hh:116
Greater or equal ( )
Definition: int.hh:930
const int min
Smallest allowed integer value.
Definition: int.hh:118
const LinIntExpr & operator=(const LinIntExpr &e)
Assignment operator.
Definition: int-expr.cpp:491
Gecode::IntSet d(v, 7)
Gecode::FloatVal c(-8, 8)
int p
Number of positive literals for node type.
Definition: bool-expr.cpp:232
T * alloc(long unsigned int n)
Allocate block of n objects of type T from heap.
Definition: heap.hpp:431
A slice of a matrix.
Definition: minimodel.hh:2058
Int::Linear::Term< Int::IntView > * ti
Integer views and coefficients.
Definition: int-expr.cpp:55
int n
Number of negative literals for node type.
Definition: bool-expr.cpp:234
Equality ( )
Definition: int.hh:926
int n_int
Integer variables in tree.
Definition: int-expr.cpp:45
Gecode::IntArgs i({1, 2, 3, 4})
Nodes for linear expressions.
Definition: int-expr.cpp:40
IntRelType
Relation types for integers.
Definition: int.hh:925
FloatVal operator+(const FloatVal &x)
Definition: val.hpp:164
~Node(void)
Destructor.
Definition: int-expr.cpp:97
BoolVar x_bool
Boolean variable (potentially)
Definition: int-expr.cpp:66
bool decrement(void)
Decrement reference count and possibly free memory.
Definition: int-expr.cpp:124
Class to set group information when a post function is executed.
Definition: core.hpp:945
int val(void) const
Return assigned value.
Definition: int.hpp:56
bool failed(void) const
Check whether corresponding space is failed.
Definition: core.hpp:3975
struct Gecode::@593::NNF::@62::@63 b
For binary nodes (and, or, eqv)
unsigned int size(I &i)
Size of all ranges of range iterator i.
int a
Coefficient and offset.
Definition: int-expr.cpp:62
LinIntExpr(void)
Default constructor.
Definition: int-expr.cpp:349
ArrayTraits< A >::ArgsType ArgsType
The type of the Args-array type for ValueType values.
Definition: minimodel.hh:2127
void post(Home home, IntRelType irt, IntPropLevel ipl) const
Post propagator.
Definition: int-expr.cpp:156
Less ( )
Definition: int.hh:929
const int * pi[]
Definition: photo.cpp:14262
NodeType
Type of linear expression.
Definition: minimodel.hh:150
Passing integer variables.
Definition: int.hh:656
Passing integer arguments.
Definition: int.hh:628
Passing Boolean variables.
Definition: int.hh:712
Non-linear expression.
Definition: minimodel.hh:154
Node(void)
Default constructor.
Definition: int-expr.cpp:93
BoolVar expr(Home home, const BoolExpr &e, IntPropLevel ipl)
Post Boolean expression and return its value.
Definition: bool-expr.cpp:627
Boolean integer variables.
Definition: int.hh:512
Post propagator for SetVar SetOpType SetVar SetRelType r
Definition: set.hh:767
void min(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition: arithmetic.cpp:67
ArrayTraits< A >::ArgsType ArgsType
The type of the Args-array type for ValueType values.
Definition: minimodel.hh:2061
IntPropLevel
Propagation levels for integer propagators.
Definition: int.hh:974
virtual IntVar post(Home home, IntVar *ret, IntPropLevel ipl) const =0
Return variable constrained to be equal to the expression.
Post propagator for SetVar SetOpType SetVar y
Definition: set.hh:767
FloatVal operator*(const FloatVal &x, const FloatVal &y)
Definition: val.hpp:200
void free(T *b, long unsigned int n)
Delete n objects starting at b.
Definition: heap.hpp:457
~LinIntExpr(void)
Destructor.
Definition: int-expr.cpp:500
Sum of integer variables.
Definition: minimodel.hh:155
Linear expressions over integer variables.
Definition: minimodel.hh:140
int n_bool
Boolean variables in tree.
Definition: int-expr.cpp:47
Integer variables.
Definition: int.hh:371
Heap heap
The single global heap.
Definition: heap.cpp:44
void estimate(Term< View > *t, int n, int c, int &l, int &u)
Estimate lower and upper bounds.
Definition: post.hpp:41
NonLinIntExpr * nle(void) const
Return non-linear expression inside, or NULL if not non-linear.
Definition: int-expr.cpp:345
Sum of Boolean variables.
Definition: minimodel.hh:156
bool valid(int n)
Return whether n is in range.
Definition: limits.hpp:37
Subtraction of linear terms.
Definition: minimodel.hh:158
void fill(Home home, IntPropLevel ipl, 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:507
Post propagator for SetVar x
Definition: set.hh:767
NonLinIntExpr * ne
Non-linear expression.
Definition: int-expr.cpp:59
Matrix-interface for arrays.
Definition: minimodel.hh:2048
Class for describing linear term .
Definition: linear.hh:1336
Integer constant.
Definition: minimodel.hh:151
Gecode toplevel namespace
LinFloatExpr sum(const FloatVarArgs &x)
Construct linear float expression as sum of float variables.
Definition: float-expr.cpp:546
ArgsType const get_array(void) const
Return an Args-array of the contents of the matrix.
Definition: matrix.hpp:149
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
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
Home class for posting propagators
Definition: core.hpp:853
Exception: Arguments are of different size
Definition: exception.hpp:73
#define GECODE_NEVER
Assert that this command is never executed.
Definition: macros.hpp:56
const unsigned int slice
Size of a slice in a portfolio and scale factor for restarts(in number of failures) ...
Definition: search.hh:128
struct Gecode::@593::NNF::@62::@64 a
For atomic nodes.
union Gecode::LinIntExpr::Node::@66 sum
Sum of integer or Boolean variables, or non-linear expression.
void post(Home home, FloatRelType frt) const
Post propagator.
Definition: float-expr.cpp:152
int val(void) const
Return assigned value.
Definition: bool.hpp:57