int-expr.cpp
Go to the documentation of this file.
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Christian Schulte <schulte@gecode.org>
*
* Copyright:
* Christian Schulte, 2010
*
* This file is part of Gecode, the generic constraint
* development environment:
* http://www.gecode.org
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <gecode/minimodel.hh>
#include <gecode/int/linear.hh>
namespace Gecode {
class LinIntExpr::Node {
public:
unsigned int use;
int n_int;
int n_bool;
NodeType t;
Node *l, *r;
union {
Int::Linear::Term<Int::IntView>* ti;
Int::Linear::Term<Int::BoolView>* tb;
NonLinIntExpr* ne;
} sum;
int a, c;
IntVar x_int;
BoolVar x_bool;
Node(void);
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;
int fill(Home home, const IntPropLevels& ipls,
Int::Linear::Term<Int::IntView>* ti,
Int::Linear::Term<Int::BoolView>* tb) const;
bool decrement(void);
~Node(void);
static void* operator new(size_t size);
static void operator delete(void* p,size_t size);
};
/*
* Operations for nodes
*
*/
forceinline
LinIntExpr::Node::Node(void) : use(1) {
}
forceinline
LinIntExpr::Node::~Node(void) {
switch (t) {
case NT_SUM_INT:
if (n_int > 0)
heap.free<Int::Linear::Term<Int::IntView> >(sum.ti,n_int);
break;
case NT_SUM_BOOL:
if (n_bool > 0)
heap.free<Int::Linear::Term<Int::BoolView> >(sum.tb,n_bool);
break;
case NT_NONLIN:
delete sum.ne;
break;
default: ;
}
}
forceinline void*
LinIntExpr::Node::operator new(size_t size) {
return heap.ralloc(size);
}
forceinline void
LinIntExpr::Node::operator delete(void* p, size_t) {
heap.rfree(p);
}
bool
LinIntExpr::Node::decrement(void) {
if (--use == 0) {
if ((l != nullptr) && l->decrement())
delete l;
if ((r != nullptr) && r->decrement())
delete r;
return true;
}
return false;
}
/*
* Operations for expressions
*
*/
LinIntExpr::LinIntExpr(const LinIntExpr& e)
: n(e.n) {
n->use++;
}
int
LinIntExpr::Node::fill(Home home, const IntPropLevels& ipls,
Int::Linear::Term<Int::IntView>* ti,
Int::Linear::Term<Int::BoolView>* tb) const {
long long int d=0;
fill(home,ipls,ti,tb,1,d);
Int::Limits::check(d,"MiniModel::LinIntExpr");
return static_cast<int>(d);
}
void
LinIntExpr::post(Home home, IntRelType irt,
const IntPropLevels& ipls) const {
if (home.failed()) return;
Region r;
if (n->n_bool == 0) {
// Only integer variables
if (n->t==NT_ADD && n->l == nullptr && n->r->t==NT_NONLIN) {
n->r->sum.ne->post(home,irt,-n->c,ipls);
} else if (n->t==NT_SUB && n->r->t==NT_NONLIN && n->l==nullptr) {
switch (irt) {
case IRT_LQ: irt=IRT_GQ; break;
case IRT_LE: irt=IRT_GR; break;
case IRT_GQ: irt=IRT_LQ; break;
case IRT_GR: irt=IRT_LE; break;
default: break;
}
n->r->sum.ne->post(home,irt,n->c,ipls);
} else if (irt==IRT_EQ &&
n->t==NT_SUB && n->r->t==NT_NONLIN &&
n->l != nullptr && n->l->t==NT_VAR_INT
&& n->l->a==1) {
(void) n->r->sum.ne->post(home,&n->l->x_int,ipls);
} else if (irt==IRT_EQ &&
n->t==NT_SUB && n->r->t==NT_VAR_INT &&
n->l != nullptr && n->l->t==NT_NONLIN
&& n->r->a==1) {
(void) n->l->sum.ne->post(home,&n->r->x_int,ipls);
} else {
Int::Linear::Term<Int::IntView>* its =
r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int);
int c = n->fill(home,ipls,its,nullptr);
Int::Linear::post(home, its, n->n_int, irt, -c,
(n->n_int > 2) ? ipls.linear() : ipls.linear2());
}
} else if (n->n_int == 0) {
// Only Boolean variables
Int::Linear::Term<Int::BoolView>* bts =
r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
int c = n->fill(home,ipls,nullptr,bts);
Int::Linear::post(home, bts, n->n_bool, irt, -c,
(n->n_bool > 2) ? ipls.linear() : ipls.linear2());
} else if (n->n_bool == 1) {
// Integer variables and only one Boolean variable
Int::Linear::Term<Int::IntView>* its =
r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
Int::Linear::Term<Int::BoolView>* bts =
r.alloc<Int::Linear::Term<Int::BoolView> >(1);
int c = n->fill(home,ipls,its,bts);
IntVar x(home,0,1);
channel(home,bts[0].x,x);
its[n->n_int].x = x;
its[n->n_int].a = bts[0].a;
Int::Linear::post(home, its, n->n_int+1, irt, -c,
(n->n_int > 1) ? ipls.linear() : ipls.linear2());
} else {
// Both integer and Boolean variables
Int::Linear::Term<Int::IntView>* its =
r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
Int::Linear::Term<Int::BoolView>* bts =
r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
int c = n->fill(home,ipls,its,bts);
int min, max;
Int::Linear::estimate(&bts[0],n->n_bool,0,min,max);
IntVar x(home,min,max);
its[n->n_int].x = x; its[n->n_int].a = 1;
Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0,
(n->n_bool > 2) ? ipls.linear() : ipls.linear2());
Int::Linear::post(home, its, n->n_int+1, irt, -c,
(n->n_int > 1) ? ipls.linear() : ipls.linear2());
}
}
void
LinIntExpr::post(Home home, IntRelType irt, const BoolVar& b,
const IntPropLevels& ipls) const {
if (home.failed()) return;
Region r;
if (n->n_bool == 0) {
// Only integer variables
if (n->t==NT_ADD && n->l==nullptr && n->r->t==NT_NONLIN) {
n->r->sum.ne->post(home,irt,-n->c,b,ipls);
} else if (n->t==NT_SUB && n->l==nullptr && n->r->t==NT_NONLIN) {
switch (irt) {
case IRT_LQ: irt=IRT_GQ; break;
case IRT_LE: irt=IRT_GR; break;
case IRT_GQ: irt=IRT_LQ; break;
case IRT_GR: irt=IRT_LE; break;
default: break;
}
n->r->sum.ne->post(home,irt,n->c,b,ipls);
} else {
Int::Linear::Term<Int::IntView>* its =
r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int);
int c = n->fill(home,ipls,its,nullptr);
Int::Linear::post(home, its, n->n_int, irt, -c, b,
(n->n_int > 2) ? ipls.linear() : ipls.linear2());
}
} else if (n->n_int == 0) {
// Only Boolean variables
Int::Linear::Term<Int::BoolView>* bts =
r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
int c = n->fill(home,ipls,nullptr,bts);
Int::Linear::post(home, bts, n->n_bool, irt, -c, b,
(n->n_bool > 2) ? ipls.linear() : ipls.linear2());
} else if (n->n_bool == 1) {
// Integer variables and only one Boolean variable
Int::Linear::Term<Int::IntView>* its =
r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
Int::Linear::Term<Int::BoolView>* bts =
r.alloc<Int::Linear::Term<Int::BoolView> >(1);
int c = n->fill(home,ipls,its,bts);
IntVar x(home,0,1);
channel(home,bts[0].x,x);
its[n->n_int].x = x;
its[n->n_int].a = bts[0].a;
Int::Linear::post(home, its, n->n_int+1, irt, -c, b,
(n->n_int > 1) ? ipls.linear() : ipls.linear2());
} else {
// Both integer and Boolean variables
Int::Linear::Term<Int::IntView>* its =
r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
Int::Linear::Term<Int::BoolView>* bts =
r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
int c = n->fill(home,ipls,its,bts);
int min, max;
Int::Linear::estimate(&bts[0],n->n_bool,0,min,max);
IntVar x(home,min,max);
its[n->n_int].x = x; its[n->n_int].a = 1;
Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0,
(n->n_int > 1) ? ipls.linear() : ipls.linear2());
Int::Linear::post(home, its, n->n_int+1, irt, -c, b,
(n->n_bool > 2) ? ipls.linear() : ipls.linear2());
}
}
IntVar
LinIntExpr::post(Home home, const IntPropLevels& ipls) const {
if (home.failed()) return IntVar(home,0,0);
Region r;
if (n->n_bool == 0) {
// Only integer variables
Int::Linear::Term<Int::IntView>* its =
r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
int c = n->fill(home,ipls,its,nullptr);
if ((n->n_int == 1) && (c == 0) && (its[0].a == 1))
return its[0].x;
int min, max;
Int::Linear::estimate(&its[0],n->n_int,c,min,max);
IntVar x(home, min, max);
its[n->n_int].x = x; its[n->n_int].a = -1;
Int::Linear::post(home, its, n->n_int+1, IRT_EQ, -c,
(n->n_int > 1) ? ipls.linear() : ipls.linear2());
return x;
} else if (n->n_int == 0) {
// Only Boolean variables
Int::Linear::Term<Int::BoolView>* bts =
r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
int c = n->fill(home,ipls,nullptr,bts);
int min, max;
Int::Linear::estimate(&bts[0],n->n_bool,c,min,max);
IntVar x(home, min, max);
Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, -c,
(n->n_bool > 2) ? ipls.linear() : ipls.linear2());
return x;
} else if (n->n_bool == 1) {
// Integer variables and single Boolean variable
Int::Linear::Term<Int::IntView>* its =
r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+2);
Int::Linear::Term<Int::BoolView>* bts =
r.alloc<Int::Linear::Term<Int::BoolView> >(1);
int c = n->fill(home,ipls,its,bts);
IntVar x(home, 0, 1);
channel(home, x, bts[0].x);
its[n->n_int].x = x; its[n->n_int].a = bts[0].a;
int y_min, y_max;
Int::Linear::estimate(&its[0],n->n_int+1,c,y_min,y_max);
IntVar y(home, y_min, y_max);
its[n->n_int+1].x = y; its[n->n_int+1].a = -1;
Int::Linear::post(home, its, n->n_int+2, IRT_EQ, -c, ipls.linear());
return y;
} else {
// Both integer and Boolean variables
Int::Linear::Term<Int::IntView>* its =
r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+2);
Int::Linear::Term<Int::BoolView>* bts =
r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
int c = n->fill(home,ipls,its,bts);
int x_min, x_max;
Int::Linear::estimate(&bts[0],n->n_bool,0,x_min,x_max);
IntVar x(home, x_min, x_max);
Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0,
(n->n_bool > 2) ? ipls.linear() : ipls.linear2());
its[n->n_int].x = x; its[n->n_int].a = 1;
int y_min, y_max;
Int::Linear::estimate(&its[0],n->n_int+1,c,y_min,y_max);
IntVar y(home, y_min, y_max);
its[n->n_int+1].x = y; its[n->n_int+1].a = -1;
Int::Linear::post(home, its, n->n_int+2, IRT_EQ, -c, ipls.linear());
return y;
}
}
NonLinIntExpr*
LinIntExpr::nle(void) const {
return n->t == NT_NONLIN ? n->sum.ne : nullptr;
}
LinIntExpr::LinIntExpr(void) :
n(new Node) {
n->n_int = n->n_bool = 0;
n->t = NT_VAR_INT;
n->l = n->r = nullptr;
n->a = 0;
}
LinIntExpr::LinIntExpr(int c) :
n(new Node) {
n->n_int = n->n_bool = 0;
n->t = NT_CONST;
n->l = n->r = nullptr;
n->a = 0;
Int::Limits::check(c,"MiniModel::LinIntExpr");
n->c = c;
}
LinIntExpr::LinIntExpr(const IntVar& x, int a) :
n(new Node) {
n->n_int = 1;
n->n_bool = 0;
n->t = NT_VAR_INT;
n->l = n->r = nullptr;
n->a = a;
n->x_int = x;
}
LinIntExpr::LinIntExpr(const BoolVar& x, int a) :
n(new Node) {
n->n_int = 0;
n->n_bool = 1;
n->t = NT_VAR_BOOL;
n->l = n->r = nullptr;
n->a = a;
n->x_bool = x;
}
LinIntExpr::LinIntExpr(const IntVarArgs& x) :
n(new Node) {
n->n_int = x.size();
n->n_bool = 0;
n->t = NT_SUM_INT;
n->l = n->r = nullptr;
if (x.size() > 0) {
n->sum.ti = heap.alloc<Int::Linear::Term<Int::IntView> >(x.size());
for (int i=x.size(); i--; ) {
n->sum.ti[i].x = x[i];
n->sum.ti[i].a = 1;
}
}
}
LinIntExpr::LinIntExpr(const IntArgs& a, const IntVarArgs& x) :
n(new Node) {
if (a.size() != x.size())
throw Int::ArgumentSizeMismatch("MiniModel::LinIntExpr");
n->n_int = x.size();
n->n_bool = 0;
n->t = NT_SUM_INT;
n->l = n->r = nullptr;
if (x.size() > 0) {
n->sum.ti = heap.alloc<Int::Linear::Term<Int::IntView> >(x.size());
for (int i=x.size(); i--; ) {
n->sum.ti[i].x = x[i];
n->sum.ti[i].a = a[i];
}
}
}
LinIntExpr::LinIntExpr(const BoolVarArgs& x) :
n(new Node) {
n->n_int = 0;
n->n_bool = x.size();
n->t = NT_SUM_BOOL;
n->l = n->r = nullptr;
if (x.size() > 0) {
n->sum.tb = heap.alloc<Int::Linear::Term<Int::BoolView> >(x.size());
for (int i=x.size(); i--; ) {
n->sum.tb[i].x = x[i];
n->sum.tb[i].a = 1;
}
}
}
LinIntExpr::LinIntExpr(const IntArgs& a, const BoolVarArgs& x) :
n(new Node) {
if (a.size() != x.size())
throw Int::ArgumentSizeMismatch("MiniModel::LinIntExpr");
n->n_int = 0;
n->n_bool = x.size();
n->t = NT_SUM_BOOL;
n->l = n->r = nullptr;
if (x.size() > 0) {
n->sum.tb = heap.alloc<Int::Linear::Term<Int::BoolView> >(x.size());
for (int i=x.size(); i--; ) {
n->sum.tb[i].x = x[i];
n->sum.tb[i].a = a[i];
}
}
}
LinIntExpr::LinIntExpr(const LinIntExpr& e0, NodeType t, const LinIntExpr& e1) :
n(new Node) {
n->n_int = e0.n->n_int + e1.n->n_int;
n->n_bool = e0.n->n_bool + e1.n->n_bool;
n->t = t;
n->l = e0.n; n->l->use++;
n->r = e1.n; n->r->use++;
}
LinIntExpr::LinIntExpr(const LinIntExpr& e, NodeType t, int c) :
n(new Node) {
n->n_int = e.n->n_int;
n->n_bool = e.n->n_bool;
n->t = t;
n->l = nullptr;
n->r = e.n; n->r->use++;
n->c = c;
}
LinIntExpr::LinIntExpr(int a, const LinIntExpr& e) :
n(new Node) {
n->n_int = e.n->n_int;
n->n_bool = e.n->n_bool;
n->t = NT_MUL;
n->l = e.n; n->l->use++;
n->r = nullptr;
n->a = a;
}
LinIntExpr::LinIntExpr(NonLinIntExpr* e) :
n(new Node) {
n->n_int = 1;
n->n_bool = 0;
n->t = NT_NONLIN;
n->l = n->r = nullptr;
n->a = 0;
n->sum.ne = e;
}
const LinIntExpr&
LinIntExpr::operator =(const LinIntExpr& e) {
if (this != &e) {
if (n->decrement())
delete n;
n = e.n; n->use++;
}
return *this;
}
LinIntExpr::~LinIntExpr(void) {
if (n->decrement())
delete n;
}
void
LinIntExpr::Node::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 {
switch (this->t) {
case NT_CONST:
Int::Limits::check(m*c,"MiniModel::LinIntExpr");
d += m*c;
break;
case NT_VAR_INT:
Int::Limits::check(m*a,"MiniModel::LinIntExpr");
ti->a=static_cast<int>(m*a); ti->x=x_int; ti++;
break;
case NT_NONLIN:
ti->a=static_cast<int>(m); ti->x=sum.ne->post(home, nullptr, ipls); ti++;
break;
case NT_VAR_BOOL:
Int::Limits::check(m*a,"MiniModel::LinIntExpr");
tb->a=static_cast<int>(m*a); tb->x=x_bool; tb++;
break;
case NT_SUM_INT:
for (int i=n_int; i--; ) {
Int::Limits::check(m*sum.ti[i].a,"MiniModel::LinIntExpr");
ti[i].x = sum.ti[i].x; ti[i].a = static_cast<int>(m*sum.ti[i].a);
}
ti += n_int;
break;
case NT_SUM_BOOL:
for (int i=n_bool; i--; ) {
Int::Limits::check(m*sum.tb[i].a,"MiniModel::LinIntExpr");
tb[i].x = sum.tb[i].x; tb[i].a = static_cast<int>(m*sum.tb[i].a);
}
tb += n_bool;
break;
case NT_ADD:
if (l == nullptr) {
Int::Limits::check(m*c,"MiniModel::LinIntExpr");
d += m*c;
} else {
l->fill(home,ipls,ti,tb,m,d);
}
r->fill(home,ipls,ti,tb,m,d);
break;
case NT_SUB:
if (l == nullptr) {
Int::Limits::check(m*c,"MiniModel::LinIntExpr");
d += m*c;
} else {
l->fill(home,ipls,ti,tb,m,d);
}
r->fill(home,ipls,ti,tb,-m,d);
break;
case NT_MUL:
Int::Limits::check(m*a,"MiniModel::LinIntExpr");
l->fill(home,ipls,ti,tb,m*a,d);
break;
default:
GECODE_NEVER;
}
}
/*
* Operators
*
*/
LinIntExpr
operator +(int c, const IntVar& x) {
if (x.assigned() &&
Int::Limits::valid(static_cast<long long int>(c)+x.val()))
return LinIntExpr(c+x.val());
else
return LinIntExpr(x,LinIntExpr::NT_ADD,c);
}
LinIntExpr
operator +(int c, const BoolVar& x) {
if (x.assigned() &&
Int::Limits::valid(static_cast<long long int>(c)+x.val()))
return LinIntExpr(c+x.val());
else
return LinIntExpr(x,LinIntExpr::NT_ADD,c);
}
LinIntExpr
operator +(int c, const LinIntExpr& e) {
return LinIntExpr(e,LinIntExpr::NT_ADD,c);
}
LinIntExpr
operator +(const IntVar& x, int c) {
if (x.assigned() &&
Int::Limits::valid(static_cast<long long int>(c)+x.val()))
return LinIntExpr(c+x.val());
else
return LinIntExpr(x,LinIntExpr::NT_ADD,c);
}
LinIntExpr
operator +(const BoolVar& x, int c) {
if (x.assigned() &&
Int::Limits::valid(static_cast<long long int>(c)+x.val()))
return LinIntExpr(c+x.val());
else
return LinIntExpr(x,LinIntExpr::NT_ADD,c);
}
LinIntExpr
operator +(const LinIntExpr& e, int c) {
return LinIntExpr(e,LinIntExpr::NT_ADD,c);
}
LinIntExpr
operator +(const IntVar& x, const IntVar& y) {
if (x.assigned())
return x.val() + y;
else if (y.assigned())
return x + y.val();
else
return LinIntExpr(x,LinIntExpr::NT_ADD,y);
}
LinIntExpr
operator +(const IntVar& x, const BoolVar& y) {
if (x.assigned())
return x.val() + y;
else if (y.assigned())
return x + y.val();
else
return LinIntExpr(x,LinIntExpr::NT_ADD,y);
}
LinIntExpr
operator +(const BoolVar& x, const IntVar& y) {
if (x.assigned())
return x.val() + y;
else if (y.assigned())
return x + y.val();
else
return LinIntExpr(x,LinIntExpr::NT_ADD,y);
}
LinIntExpr
operator +(const BoolVar& x, const BoolVar& y) {
if (x.assigned())
return x.val() + y;
else if (y.assigned())
return x + y.val();
else
return LinIntExpr(x,LinIntExpr::NT_ADD,y);
}
LinIntExpr
operator +(const IntVar& x, const LinIntExpr& e) {
if (x.assigned())
return x.val() + e;
else
return LinIntExpr(x,LinIntExpr::NT_ADD,e);
}
LinIntExpr
operator +(const BoolVar& x, const LinIntExpr& e) {
if (x.assigned())
return x.val() + e;
else
return LinIntExpr(x,LinIntExpr::NT_ADD,e);
}
LinIntExpr
operator +(const LinIntExpr& e, const IntVar& x) {
if (x.assigned())
return e + x.val();
else
return LinIntExpr(e,LinIntExpr::NT_ADD,x);
}
LinIntExpr
operator +(const LinIntExpr& e, const BoolVar& x) {
if (x.assigned())
return e + x.val();
else
return LinIntExpr(e,LinIntExpr::NT_ADD,x);
}
LinIntExpr
operator +(const LinIntExpr& e1, const LinIntExpr& e2) {
return LinIntExpr(e1,LinIntExpr::NT_ADD,e2);
}
LinIntExpr
operator -(int c, const IntVar& x) {
if (x.assigned() &&
Int::Limits::valid(static_cast<long long int>(c)-x.val()))
return LinIntExpr(c-x.val());
else
return LinIntExpr(x,LinIntExpr::NT_SUB,c);
}
LinIntExpr
operator -(int c, const BoolVar& x) {
if (x.assigned() &&
Int::Limits::valid(static_cast<long long int>(c)-x.val()))
return LinIntExpr(c-x.val());
else
return LinIntExpr(x,LinIntExpr::NT_SUB,c);
}
LinIntExpr
operator -(int c, const LinIntExpr& e) {
return LinIntExpr(e,LinIntExpr::NT_SUB,c);
}
LinIntExpr
operator -(const IntVar& x, int c) {
if (x.assigned() &&
Int::Limits::valid(x.val()-static_cast<long long int>(c)))
return LinIntExpr(x.val()-c);
else
return LinIntExpr(x,LinIntExpr::NT_ADD,-c);
}
LinIntExpr
operator -(const BoolVar& x, int c) {
if (x.assigned() &&
Int::Limits::valid(x.val()-static_cast<long long int>(c)))
return LinIntExpr(x.val()-c);
else
return LinIntExpr(x,LinIntExpr::NT_ADD,-c);
}
LinIntExpr
operator -(const LinIntExpr& e, int c) {
return LinIntExpr(e,LinIntExpr::NT_ADD,-c);
}
LinIntExpr
operator -(const IntVar& x, const IntVar& y) {
if (x.assigned())
return x.val() - y;
else if (y.assigned())
return x - y.val();
else
return LinIntExpr(x,LinIntExpr::NT_SUB,y);
}
LinIntExpr
operator -(const IntVar& x, const BoolVar& y) {
if (x.assigned())
return x.val() - y;
else if (y.assigned())
return x - y.val();
else
return LinIntExpr(x,LinIntExpr::NT_SUB,y);
}
LinIntExpr
operator -(const BoolVar& x, const IntVar& y) {
if (x.assigned())
return x.val() - y;
else if (y.assigned())
return x - y.val();
else
return LinIntExpr(x,LinIntExpr::NT_SUB,y);
}
LinIntExpr
operator -(const BoolVar& x, const BoolVar& y) {
if (x.assigned())
return x.val() - y;
else if (y.assigned())
return x - y.val();
else
return LinIntExpr(x,LinIntExpr::NT_SUB,y);
}
LinIntExpr
operator -(const IntVar& x, const LinIntExpr& e) {
if (x.assigned())
return x.val() - e;
else
return LinIntExpr(x,LinIntExpr::NT_SUB,e);
}
LinIntExpr
operator -(const BoolVar& x, const LinIntExpr& e) {
if (x.assigned())
return x.val() - e;
else
return LinIntExpr(x,LinIntExpr::NT_SUB,e);
}
LinIntExpr
operator -(const LinIntExpr& e, const IntVar& x) {
if (x.assigned())
return e - x.val();
else
return LinIntExpr(e,LinIntExpr::NT_SUB,x);
}
LinIntExpr
operator -(const LinIntExpr& e, const BoolVar& x) {
if (x.assigned())
return e - x.val();
else
return LinIntExpr(e,LinIntExpr::NT_SUB,x);
}
LinIntExpr
operator -(const LinIntExpr& e1, const LinIntExpr& e2) {
return LinIntExpr(e1,LinIntExpr::NT_SUB,e2);
}
LinIntExpr
operator -(const IntVar& x) {
if (x.assigned())
return LinIntExpr(-x.val());
else
return LinIntExpr(x,LinIntExpr::NT_SUB,0);
}
LinIntExpr
operator -(const BoolVar& x) {
if (x.assigned())
return LinIntExpr(-x.val());
else
return LinIntExpr(x,LinIntExpr::NT_SUB,0);
}
LinIntExpr
operator -(const LinIntExpr& e) {
return LinIntExpr(e,LinIntExpr::NT_SUB,0);
}
LinIntExpr
operator *(int a, const IntVar& x) {
if (a == 0)
return LinIntExpr(0);
else if (x.assigned() &&
Int::Limits::valid(static_cast<long long int>(a)*x.val()))
return LinIntExpr(a*x.val());
else
return LinIntExpr(x,a);
}
LinIntExpr
operator *(int a, const BoolVar& x) {
if (a == 0)
return LinIntExpr(0);
else if (x.assigned() &&
Int::Limits::valid(static_cast<long long int>(a)*x.val()))
return LinIntExpr(a*x.val());
else
return LinIntExpr(x,a);
}
LinIntExpr
operator *(const IntVar& x, int a) {
if (a == 0)
return LinIntExpr(0);
else if (x.assigned() &&
Int::Limits::valid(static_cast<long long int>(a)*x.val()))
return LinIntExpr(a*x.val());
else
return LinIntExpr(x,a);
}
LinIntExpr
operator *(const BoolVar& x, int a) {
if (a == 0)
return LinIntExpr(0);
else if (x.assigned() &&
Int::Limits::valid(static_cast<long long int>(a)*x.val()))
return LinIntExpr(a*x.val());
else
return LinIntExpr(x,a);
}
LinIntExpr
operator *(const LinIntExpr& e, int a) {
if (a == 0)
return LinIntExpr(0);
else
return LinIntExpr(a,e);
}
LinIntExpr
operator *(int a, const LinIntExpr& e) {
if (a == 0)
return LinIntExpr(0);
else
return LinIntExpr(a,e);
}
LinIntExpr
sum(const IntVarArgs& x) {
return LinIntExpr(x);
}
LinIntExpr
sum(const IntArgs& a, const IntVarArgs& x) {
return LinIntExpr(a,x);
}
LinIntExpr
sum(const BoolVarArgs& x) {
return LinIntExpr(x);
}
LinIntExpr
sum(const IntArgs& a, const BoolVarArgs& x) {
return LinIntExpr(a,x);
}
LinIntExpr
sum(const Slice<IntArgs>& slice) {
const Slice<IntArgs>::ArgsType & args = slice;
return sum(args);
}
LinIntExpr
sum(const Matrix<IntArgs>& matrix) {
const Matrix<IntArgs>::ArgsType & args = matrix.get_array();
return sum(args);
}
LinIntExpr
sum(const IntArgs& args) {
int sum = 0;
for (int i = 0; i<args.size(); i++)
sum += args[i];
return LinIntExpr(sum);
}
IntVar
expr(Home home, const LinIntExpr& e, const IntPropLevels& ipls) {
PostInfo pi(home);
if (!home.failed())
return e.post(home,ipls);
IntVar x(home,Int::Limits::min,Int::Limits::max);
return x;
}
}
// STATISTICS: minimodel-any
Gecode::ArgArrayBase::size
int size(void) const
Return size of array (number of elements).
Definition array.hpp:1607
Gecode::BoolVarArgs
Passing Boolean variables.
Definition int.hh:712
Gecode::BoolVar
Boolean integer variables.
Definition int.hh:512
Gecode::BoolVar::val
int val(void) const
Return assigned value.
Definition bool.hpp:57
Gecode::FloatVal::size
FloatNum size(void) const
Return size of float value (distance between maximum and minimum).
Definition val.hpp:78
Gecode::Home
Home class for posting propagators
Definition core.hpp:856
Gecode::Home::failed
bool failed(void) const
Check whether corresponding space is failed.
Definition core.hpp:4048
Gecode::IntArgs
Passing integer arguments.
Definition int.hh:628
Gecode::IntPropLevels
Class for specifying integer propagation levels used by minimodel.
Definition minimodel.hh:101
Gecode::IntPropLevels::linear
IntPropLevel linear(void) const
Return integer propagation level for non-binary linear constraints.
Definition ipl.hpp:55
Gecode::IntPropLevels::linear2
IntPropLevel linear2(void) const
Return integer propagation level for binary linear constraints.
Definition ipl.hpp:47
Gecode::IntVarArgs
Passing integer variables.
Definition int.hh:656
Gecode::IntVar
Integer variables.
Definition int.hh:371
Gecode::IntVar::val
int val(void) const
Return assigned value.
Definition int.hpp:56
Gecode::Int::ArgumentSizeMismatch
Exception: Arguments are of different size
Definition exception.hpp:73
Gecode::Int::Linear::Term
Class for describing linear term .
Definition linear.hh:1336
Gecode::Int::Linear::Term::x
View x
View.
Definition linear.hh:1341
Gecode::Int::Linear::Term::a
int a
Coefficient.
Definition linear.hh:1339
Gecode::LinIntExpr::Node
Nodes for linear expressions.
Definition int-expr.cpp:40
Gecode::LinIntExpr::Node::decrement
bool decrement(void)
Decrement reference count and possibly free memory.
Definition int-expr.cpp:124
Gecode::LinIntExpr::Node::c
int c
Definition int-expr.cpp:62
Gecode::LinIntExpr::Node::l
Node * l
Subexpressions.
Definition int-expr.cpp:51
Gecode::LinIntExpr::Node::sum
union Gecode::LinIntExpr::Node::@261231010026300320017355123073322333035126115356 sum
Sum of integer or Boolean variables, or non-linear expression.
Gecode::LinIntExpr::Node::ti
Int::Linear::Term< Int::IntView > * ti
Integer views and coefficients.
Definition int-expr.cpp:55
Gecode::LinIntExpr::Node::use
unsigned int use
Nodes are reference counted.
Definition int-expr.cpp:43
Gecode::LinIntExpr::Node::n_int
int n_int
Integer variables in tree.
Definition int-expr.cpp:45
Gecode::LinIntExpr::Node::x_int
IntVar x_int
Integer variable (potentially).
Definition int-expr.cpp:64
Gecode::LinIntExpr::Node::t
NodeType t
Type of expression.
Definition int-expr.cpp:49
Gecode::LinIntExpr::Node::ne
NonLinIntExpr * ne
Non-linear expression.
Definition int-expr.cpp:59
Gecode::LinIntExpr::Node::x_bool
BoolVar x_bool
Boolean variable (potentially).
Definition int-expr.cpp:66
Gecode::LinIntExpr::Node::fill
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
Gecode::LinIntExpr::Node::~Node
~Node(void)
Destructor.
Definition int-expr.cpp:97
Gecode::LinIntExpr::Node::tb
Int::Linear::Term< Int::BoolView > * tb
Bool views and coefficients.
Definition int-expr.cpp:57
Gecode::LinIntExpr::Node::r
Node * r
Definition int-expr.cpp:51
Gecode::LinIntExpr::Node::a
int a
Coefficient and offset.
Definition int-expr.cpp:62
Gecode::LinIntExpr::Node::n_bool
int n_bool
Boolean variables in tree.
Definition int-expr.cpp:47
Gecode::LinIntExpr::Node::Node
Node(void)
Default constructor.
Definition int-expr.cpp:93
Gecode::LinIntExpr
Linear expressions over integer variables.
Definition minimodel.hh:245
Gecode::LinIntExpr::NodeType
NodeType
Type of linear expression.
Definition minimodel.hh:255
Gecode::LinIntExpr::NT_CONST
@ NT_CONST
Integer constant.
Definition minimodel.hh:256
Gecode::LinIntExpr::NT_SUB
@ NT_SUB
Subtraction of linear terms.
Definition minimodel.hh:263
Gecode::LinIntExpr::NT_SUM_BOOL
@ NT_SUM_BOOL
Sum of Boolean variables.
Definition minimodel.hh:261
Gecode::LinIntExpr::NT_ADD
@ NT_ADD
Addition of linear terms.
Definition minimodel.hh:262
Gecode::LinIntExpr::NT_SUM_INT
@ NT_SUM_INT
Sum of integer variables.
Definition minimodel.hh:260
Gecode::LinIntExpr::NT_VAR_BOOL
@ NT_VAR_BOOL
Linear term with Boolean variable.
Definition minimodel.hh:258
Gecode::LinIntExpr::NT_MUL
@ NT_MUL
Multiplication by coefficient.
Definition minimodel.hh:264
Gecode::LinIntExpr::NT_NONLIN
@ NT_NONLIN
Non-linear expression.
Definition minimodel.hh:259
Gecode::LinIntExpr::NT_VAR_INT
@ NT_VAR_INT
Linear term with integer variable.
Definition minimodel.hh:257
Gecode::LinIntExpr::LinIntExpr
LinIntExpr(void)
Default constructor.
Definition int-expr.cpp:363
Gecode::LinIntExpr::~LinIntExpr
~LinIntExpr(void)
Destructor.
Definition int-expr.cpp:514
Gecode::LinIntExpr::post
void post(Home home, IntRelType irt, const IntPropLevels &ipls) const
Post propagator.
Definition int-expr.cpp:156
Gecode::LinIntExpr::operator=
const LinIntExpr & operator=(const LinIntExpr &e)
Assignment operator.
Definition int-expr.cpp:505
Gecode::LinIntExpr::nle
NonLinIntExpr * nle(void) const
Return non-linear expression inside, or null if not non-linear.
Definition int-expr.cpp:359
Gecode::Matrix
Matrix-interface for arrays.
Definition minimodel.hh:2161
Gecode::Matrix::get_array
ArgsType const get_array(void) const
Return an Args-array of the contents of the matrix.
Definition matrix.hpp:149
Gecode::Matrix::ArgsType
ArrayTraits< A >::ArgsType ArgsType
The type of the Args-array type for ValueType values.
Definition minimodel.hh:2166
Gecode::NonLinIntExpr
Base class for non-linear expressions over integer variables.
Definition minimodel.hh:215
Gecode::PostInfo
Class to set group information when a post function is executed.
Definition core.hpp:948
Gecode::Region
Handle to region.
Definition region.hpp:55
Gecode::Slice
A slice of a matrix.
Definition minimodel.hh:2097
Gecode::Slice::ArgsType
ArrayTraits< A >::ArgsType ArgsType
The type of the Args-array type for ValueType values.
Definition minimodel.hh:2100
Gecode::VarImpVar::assigned
bool assigned(void) const
Test whether view is assigned.
Definition var.hpp:111
pi
const int * pi[]
Definition photo.cpp:14262
Gecode::Int::Linear::post
void post(Home home, Term< IntView > *t, int n, IntRelType irt, int c, IntPropLevel=IPL_DEF)
Post propagator for linear constraint over integers.
Definition int-post.cpp:219
Gecode::heap
Heap heap
The single global heap.
Definition heap.cpp:44
Gecode::IntRelType
IntRelType
Relation types for integers.
Definition int.hh:925
Gecode::IRT_EQ
@ IRT_EQ
Equality ( ).
Definition int.hh:926
Gecode::IRT_GQ
@ IRT_GQ
Greater or equal ( ).
Definition int.hh:930
Gecode::IRT_LE
@ IRT_LE
Less ( ).
Definition int.hh:929
Gecode::IRT_GR
@ IRT_GR
Greater ( ).
Definition int.hh:931
Gecode::IRT_LQ
@ IRT_LQ
Less or equal ( ).
Definition int.hh:928
linear.hh
minimodel.hh
Gecode::Int::Limits::check
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
Gecode::Int::Limits::min
const int min
Smallest allowed integer value.
Definition int.hh:118
Gecode::Int::Limits::valid
bool valid(int n)
Return whether n is in range.
Definition limits.hpp:37
Gecode::Int::Limits::max
const int max
Largest allowed integer value.
Definition int.hh:116
Gecode::Int::Linear::estimate
void estimate(Term< View > *t, int n, int c, int &l, int &u)
Estimate lower and upper bounds.
Definition post.hpp:41
Gecode
Gecode toplevel namespace
Gecode::operator-
FloatVal operator-(const FloatVal &x)
Definition val.hpp:168
Gecode::operator+
FloatVal operator+(const FloatVal &x)
Definition val.hpp:164
Gecode::channel
void channel(Home home, FloatVar x0, IntVar x1)
Post propagator for channeling a float and an integer variable .
Definition channel.cpp:41
Gecode::expr
IntVar expr(Home home, const LinIntExpr &e, const IntPropLevels &ipls=IntPropLevels::def)
Post linear expression and return its value.
Definition int-expr.cpp:915
Gecode::min
void min(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition arithmetic.cpp:67
Gecode::sum
LinIntExpr sum(const IntVarArgs &x)
Construct linear expression as sum of integer variables.
Definition int-expr.cpp:880
Gecode::max
void max(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition arithmetic.cpp:49
Gecode::operator*
FloatVal operator*(const FloatVal &x, const FloatVal &y)
Definition val.hpp:200
forceinline
#define forceinline
Definition config.hpp:187
GECODE_NEVER
#define GECODE_NEVER
Assert that this command is never executed.
Definition macros.hpp:56