/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Guido Tack * * Copyright: * Guido Tack, 2004 * * Last modified: * $Date: 2008-02-27 02:25:24 +0100 (Wed, 27 Feb 2008) $ by $Author: schulte $ * $Revision: 6315 $ * * 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. * */ namespace Gecode { namespace MiniModel { /* * Operations for nodes * */ template forceinline LinExpr::Node::Node(void) : use(1) { } template forceinline void* LinExpr::Node::operator new(size_t size) { return Memory::malloc(size); } template forceinline void LinExpr::Node::operator delete(void* p, size_t) { Memory::free(p); } template bool LinExpr::Node::decrement(void) { if (--use == 0) { if ((l != NULL) && l->decrement()) delete l; if ((r != NULL) && r->decrement()) delete r; return true; } return false; } template int LinExpr::Node::fill(Int::Linear::Term t[], int i, int m, int c_i, int& c_o) const { switch (this->t) { case NT_VAR: c_o = c_i; if (a != 0) { t[i].a=m*a; t[i].x=x; return i+1; } else { return i; } case NT_ADD: if (l == NULL) { return r->fill(t,i,m,c_i+m*c,c_o); } else { int c_m = 0; i = l->fill(t,i,m,c_i,c_m); return r->fill(t,i,m,c_m,c_o); } case NT_SUB: if (l == NULL) { return r->fill(t,i,-m,c_i+m*c,c_o); } else { int c_m = 0; i = l->fill(t,i,m,c_i,c_m); return r->fill(t,i,-m,c_m,c_o); } case NT_MUL: return l->fill(t,i,a*m,c_i,c_o); default: GECODE_NEVER; } GECODE_NEVER; return 0; } /* * Operations for expressions * */ template inline LinExpr::LinExpr(void) : n(new Node) { n->n = 0; n->t = NT_VAR; n->l = n->r = NULL; n->a = 0; } template inline LinExpr::LinExpr(const Var& x, int a) : n(new Node) { n->n = 1; n->t = NT_VAR; n->l = n->r = NULL; n->a = a; n->x = x; } template inline LinExpr::LinExpr(const LinExpr& e0, NodeType t, const LinExpr& e1) : n(new Node) { n->n = e0.n->n+e1.n->n; n->t = t; n->l = e0.n; n->l->use++; n->r = e1.n; n->r->use++; } template inline LinExpr::LinExpr(const LinExpr& e, NodeType t, int c) : n(new Node) { n->n = e.n->n; n->t = t; n->l = NULL; n->r = e.n; n->r->use++; n->c = c; } template inline LinExpr::LinExpr(int a, const LinExpr& e) : n(new Node) { n->n = e.n->n; n->t = NT_MUL; n->l = e.n; n->l->use++; n->r = NULL; n->a = a; } template inline LinExpr::LinExpr(const LinExpr& e) : n(e.n) { n->use++; } template inline const LinExpr& LinExpr::operator=(const LinExpr& e) { if (this != &e) { if (n->decrement()) delete n; n = e.n; n->use++; } return *this; } template forceinline LinExpr::~LinExpr(void) { if (n->decrement()) delete n; } template inline void LinExpr::post(Space* home, IntRelType irt, IntConLevel icl, PropKind pk) const { GECODE_AUTOARRAY(Int::Linear::Term, ts, n->n); int c_o = 0; int i = n->fill(ts,0,1,0,c_o); Int::Linear::post(home, ts, i, irt, -c_o, icl, pk); } template inline void LinExpr::post(Space* home, IntRelType irt, const BoolVar& b, IntConLevel icl, PropKind pk) const { GECODE_AUTOARRAY(Int::Linear::Term, ts, n->n); int c_o = 0; int i = n->fill(ts,0,1,0,c_o); Int::Linear::post(home, ts, i, irt, -c_o, b, icl, pk); } template <> inline IntVar LinExpr::post(Space* home, IntConLevel icl, PropKind pk) const { GECODE_AUTOARRAY(Int::Linear::Term, ts, n->n+1); int c_o = 0; int i = n->fill(ts,0,1,0,c_o); int min, max; Int::Linear::estimate(&ts[0],i,c_o,min,max); IntVar x(home, min, max); ts[i].x = x; ts[i].a = -1; Int::Linear::post(home, ts, i+1, IRT_EQ, -c_o, icl, pk); return x; } template <> inline IntVar LinExpr::post(Space* home, IntConLevel icl, PropKind pk) const { GECODE_AUTOARRAY(Int::Linear::Term, ts, n->n+1); int c_o = 0; int i = n->fill(ts,0,1,0,c_o); int min, max; Int::Linear::estimate(&ts[0],i,c_o,min,max); IntVar x(home, min, max); Int::Linear::post(home, ts, i, IRT_EQ, x, -c_o, icl, pk); return x; } }} inline Gecode::MiniModel::LinExpr operator+(int c, const Gecode::MiniModel::LinExpr& e) { return Gecode::MiniModel::LinExpr(e,Gecode::MiniModel::LinExpr::NT_ADD,c); } inline Gecode::MiniModel::LinExpr operator+(const Gecode::MiniModel::LinExpr& e, int c) { return Gecode::MiniModel::LinExpr(e,Gecode::MiniModel::LinExpr::NT_ADD,c); } inline Gecode::MiniModel::LinExpr operator+(const Gecode::MiniModel::LinExpr& e1, const Gecode::MiniModel::LinExpr& e2) { return Gecode::MiniModel::LinExpr(e1,Gecode::MiniModel::LinExpr::NT_ADD,e2); } inline Gecode::MiniModel::LinExpr operator-(int c, const Gecode::MiniModel::LinExpr& e) { return Gecode::MiniModel::LinExpr(e,Gecode::MiniModel::LinExpr::NT_SUB,c); } inline Gecode::MiniModel::LinExpr operator-(const Gecode::MiniModel::LinExpr& e, int c) { return Gecode::MiniModel::LinExpr(e,Gecode::MiniModel::LinExpr::NT_ADD,-c); } inline Gecode::MiniModel::LinExpr operator-(const Gecode::MiniModel::LinExpr& e1, const Gecode::MiniModel::LinExpr& e2) { return Gecode::MiniModel::LinExpr(e1,Gecode::MiniModel::LinExpr::NT_SUB,e2); } inline Gecode::MiniModel::LinExpr operator-(const Gecode::MiniModel::LinExpr& e) { return Gecode::MiniModel::LinExpr(e,Gecode::MiniModel::LinExpr::NT_SUB,0); } inline Gecode::MiniModel::LinExpr operator*(int a, const Gecode::IntVar& x) { return Gecode::MiniModel::LinExpr(x,a); } inline Gecode::MiniModel::LinExpr operator*(const Gecode::IntVar& x, int a) { return Gecode::MiniModel::LinExpr(x,a); } inline Gecode::MiniModel::LinExpr operator*(const Gecode::MiniModel::LinExpr& e, int a) { return Gecode::MiniModel::LinExpr(a,e); } inline Gecode::MiniModel::LinExpr operator*(int a, const Gecode::MiniModel::LinExpr& e) { return Gecode::MiniModel::LinExpr(a,e); } inline Gecode::MiniModel::LinExpr operator+(int c, const Gecode::MiniModel::LinExpr& e) { return Gecode::MiniModel::LinExpr(e,Gecode::MiniModel::LinExpr::NT_ADD,c); } inline Gecode::MiniModel::LinExpr operator+(const Gecode::MiniModel::LinExpr& e, int c) { return Gecode::MiniModel::LinExpr(e,Gecode::MiniModel::LinExpr::NT_ADD,c); } inline Gecode::MiniModel::LinExpr operator+(const Gecode::MiniModel::LinExpr& e1, const Gecode::MiniModel::LinExpr& e2) { return Gecode::MiniModel::LinExpr(e1,Gecode::MiniModel::LinExpr::NT_ADD,e2); } inline Gecode::MiniModel::LinExpr operator-(int c, const Gecode::MiniModel::LinExpr& e) { return Gecode::MiniModel::LinExpr(e,Gecode::MiniModel::LinExpr::NT_SUB,c); } inline Gecode::MiniModel::LinExpr operator-(const Gecode::MiniModel::LinExpr& e, int c) { return Gecode::MiniModel::LinExpr(e,Gecode::MiniModel::LinExpr::NT_ADD,-c); } inline Gecode::MiniModel::LinExpr operator-(const Gecode::MiniModel::LinExpr& e1, const Gecode::MiniModel::LinExpr& e2) { return Gecode::MiniModel::LinExpr(e1,Gecode::MiniModel::LinExpr::NT_SUB,e2); } inline Gecode::MiniModel::LinExpr operator-(const Gecode::MiniModel::LinExpr& e) { return Gecode::MiniModel::LinExpr(e,Gecode::MiniModel::LinExpr::NT_SUB,0); } inline Gecode::MiniModel::LinExpr operator*(int a, const Gecode::BoolVar& x) { return Gecode::MiniModel::LinExpr(x,a); } inline Gecode::MiniModel::LinExpr operator*(const Gecode::BoolVar& x, int a) { return Gecode::MiniModel::LinExpr(x,a); } inline Gecode::MiniModel::LinExpr operator*(const Gecode::MiniModel::LinExpr& e, int a) { return Gecode::MiniModel::LinExpr(a,e); } inline Gecode::MiniModel::LinExpr operator*(int a, const Gecode::MiniModel::LinExpr& e) { return Gecode::MiniModel::LinExpr(a,e); } namespace Gecode { forceinline IntVar post(Space*, const IntVar& x, IntConLevel, PropKind) { return x; } inline IntVar post(Space* home, int n, IntConLevel, PropKind) { IntVar x(home, n, n); return x; } template inline IntVar post(Space* home, const MiniModel::LinExpr& e, IntConLevel icl, PropKind pk) { if (!home->failed()) return e.post(home,icl,pk); IntVar x(home,Int::Limits::min,Int::Limits::max); return x; } } // STATISTICS: minimodel-any