Generated on Mon Aug 25 11:35:40 2008 for Gecode by doxygen 1.5.6

bool-expr.cc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *     Christian Schulte <schulte@gecode.org>
00006  *
00007  *  Copyright:
00008  *     Guido Tack, 2004
00009  *     Christian Schulte, 2004
00010  *
00011  *  Last modified:
00012  *     $Date: 2008-02-26 11:08:59 +0100 (Tue, 26 Feb 2008) $ by $Author: tack $
00013  *     $Revision: 6312 $
00014  *
00015  *  This file is part of Gecode, the generic constraint
00016  *  development environment:
00017  *     http://www.gecode.org
00018  *
00019  *  Permission is hereby granted, free of charge, to any person obtaining
00020  *  a copy of this software and associated documentation files (the
00021  *  "Software"), to deal in the Software without restriction, including
00022  *  without limitation the rights to use, copy, modify, merge, publish,
00023  *  distribute, sublicense, and/or sell copies of the Software, and to
00024  *  permit persons to whom the Software is furnished to do so, subject to
00025  *  the following conditions:
00026  *
00027  *  The above copyright notice and this permission notice shall be
00028  *  included in all copies or substantial portions of the Software.
00029  *
00030  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00031  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00032  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00033  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00034  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00035  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00036  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00037  *
00038  */
00039 
00040 #include "gecode/minimodel.hh"
00041 
00042 namespace Gecode { namespace MiniModel {
00043 
00044   /*
00045    * Operations for nodes
00046    *
00047    */
00048   forceinline void*
00049   BoolExpr::Node::operator new(size_t size) {
00050     return Memory::malloc(size);
00051   }
00052   
00053   forceinline void
00054   BoolExpr::Node::operator delete(void* p, size_t) {
00055     Memory::free(p);
00056   }
00057   
00058   forceinline
00059   BoolExpr::Node::Node(void) : use(1) {}
00060   
00061   bool
00062   BoolExpr::Node::decrement(void) {
00063     if (--use == 0) {
00064       if ((l != NULL) && l->decrement())
00065         delete l;
00066       if ((r != NULL) && r->decrement())
00067         delete r;
00068       return true;
00069     }
00070     return false;
00071   }
00072   
00073   BoolVar
00074   BoolExpr::Node::post(Space* home, IntConLevel icl, PropKind pk) const {
00075     if (t == NT_VAR)
00076       return x;
00077     BoolVar b(home, 0, 1);
00078     post(home, b, icl, pk);
00079     return b;
00080   }
00081   
00082   int
00083   BoolExpr::Node::post(Space* home, NodeType t, 
00084                        BoolVarArgs& b, int i, 
00085                        IntConLevel icl, PropKind pk) const {
00086     if (this->t != t) {
00087       b[i] = post(home, icl, pk);
00088       return i+1;
00089     } else {
00090       return l->post(home, t, b, r->post(home, t, b, i, icl, pk), icl, pk);
00091     }
00092   }
00093   
00094   void
00095   BoolExpr::Node::post(Space* home, BoolVar b, 
00096                        IntConLevel icl, PropKind pk) const {
00097     assert(t != NT_VAR);
00098     switch (t) {
00099     case NT_NOT:
00100       rel(home, l->post(home, icl, pk), IRT_NQ, b, icl, pk);
00101       break;
00102     case NT_AND:
00103       if (same > 2) {
00104         BoolVarArgs ba(same);
00105         (void) post(home, NT_AND, ba, 0, icl, pk);
00106         rel(home, BOT_AND, ba, b, icl, pk);
00107       } else {
00108         rel(home, 
00109             l->post(home, icl, pk), BOT_AND, r->post(home, icl, pk), b, 
00110             icl, pk);
00111       }
00112       break;
00113     case NT_OR:
00114       if (same > 2) {
00115         BoolVarArgs ba(same);
00116         (void) post(home, NT_OR, ba, 0, icl, pk);
00117         rel(home, BOT_OR, ba, b, icl, pk);
00118       } else {
00119         rel(home, 
00120             l->post(home, icl, pk), BOT_OR, r->post(home, icl, pk), b, 
00121             icl, pk);
00122       }
00123       break;
00124     case NT_IMP:
00125       rel(home, 
00126           l->post(home, icl, pk), BOT_IMP, r->post(home, icl, pk), b, 
00127           icl, pk);
00128       break;
00129     case NT_XOR:
00130       rel(home, 
00131           l->post(home, icl, pk), BOT_XOR, r->post(home, icl, pk), b, 
00132           icl, pk);
00133       break;
00134     case NT_EQV:
00135       rel(home, 
00136           l->post(home, icl, pk), BOT_EQV, r->post(home, icl, pk), b, 
00137           icl, pk);
00138       break;
00139     case NT_RLIN_INT:
00140       rl_int.post(home, b, icl, pk);
00141       break;
00142     case NT_RLIN_BOOL:
00143       rl_bool.post(home, b, icl, pk);
00144       break;
00145     default: GECODE_NEVER;
00146     }
00147   }
00148   
00149   void
00150   BoolExpr::Node::post(Space* home, bool b, 
00151                        IntConLevel icl, PropKind pk) const {
00152     if (b) {
00153       switch (t) {
00154       case NT_VAR:
00155         rel(home, x, IRT_EQ, 1);
00156         break;
00157       case NT_NOT:
00158         l->post(home, false, icl, pk);
00159         break;
00160       case NT_OR:
00161         if (same > 2) {
00162           BoolVarArgs ba(same);
00163           (void) post(home, NT_OR, ba, 0, icl, pk);
00164           rel(home, BOT_OR, ba, 1, icl, pk);
00165         } else {
00166           rel(home, 
00167               l->post(home, icl, pk), BOT_OR, r->post(home, icl, pk), 1, 
00168               icl, pk);
00169         }
00170         break;
00171       case NT_AND:
00172         l->post(home, true, icl, pk); 
00173         r->post(home, true, icl, pk);
00174         break;
00175       case NT_EQV:
00176         if ((l->t == NT_VAR) && (r->t != NT_VAR)) {
00177           r->post(home, l->x, icl, pk);
00178         } else if ((l->t != NT_VAR) && (r->t == NT_VAR)) {
00179           l->post(home, r->x, icl, pk);
00180         } else if ((l->t != NT_VAR) && (r->t != NT_VAR)) {
00181           BoolVar b(home, 0, 1);
00182           l->post(home, b, icl, pk);
00183           r->post(home, b, icl, pk);
00184         } else {
00185           BoolVar b(home, 1, 1);
00186           post(home, b, icl, pk);
00187         }
00188         break;
00189       case NT_RLIN_INT:
00190         rl_int.post(home, true, icl, pk);
00191         break;
00192       case NT_RLIN_BOOL:
00193         rl_bool.post(home, true, icl, pk);
00194         break;
00195       default:
00196         {
00197           BoolVar b(home, 1, 1);
00198           post(home, b, icl, pk);
00199         }
00200         break;
00201       }
00202     } else {
00203       switch (t) {
00204       case NT_VAR:
00205         rel(home, x, IRT_EQ, 0, icl, pk);
00206         break;
00207       case NT_NOT:
00208         l->post(home, true, icl, pk);
00209         break;
00210       case NT_OR:
00211         l->post(home, false, icl, pk); 
00212         r->post(home, false, icl, pk);
00213         break;
00214       case NT_AND:
00215         if (same > 2) {
00216           BoolVarArgs ba(same);
00217           (void) post(home, NT_AND, ba, 0, icl, pk);
00218           rel(home, BOT_AND, ba, 0, icl, pk);
00219         } else {
00220           rel(home, 
00221               l->post(home, icl, pk), BOT_AND, r->post(home, icl, pk), 0, 
00222               icl, pk);
00223         }
00224         break;
00225       case NT_IMP:
00226         l->post(home, true, icl, pk);
00227         r->post(home, false, icl, pk);
00228         break;
00229       case NT_XOR:
00230         if ((l->t == NT_VAR) && (r->t != NT_VAR)) {
00231           r->post(home, l->x, icl, pk);
00232         } else if ((l->t != NT_VAR) && (r->t == NT_VAR)) {
00233           l->post(home, r->x, icl, pk);
00234         } else if ((l->t != NT_VAR) && (r->t != NT_VAR)) {
00235           BoolVar b(home, 0, 1);
00236           l->post(home, b, icl, pk);
00237           r->post(home, b, icl, pk);
00238         } else {
00239           BoolVar b(home, 0, 0);
00240           post(home, b, icl, pk);
00241         }
00242         break;
00243       case NT_RLIN_INT:
00244         rl_int.post(home, false, icl, pk);
00245         break;
00246       case NT_RLIN_BOOL:
00247         rl_bool.post(home, false, icl, pk);
00248         break;
00249       default:
00250         {
00251           BoolVar b(home, 0, 0);
00252           post(home, b, icl, pk);
00253         }
00254         break;
00255       }
00256     }
00257   }
00258 
00259   BoolExpr::BoolExpr(const BoolVar& x) : n(new Node) {
00260     n->same = 1;
00261     n->t    = NT_VAR;
00262     n->l    = NULL;
00263     n->r    = NULL;
00264     n->x    = x;
00265   }
00266 
00267   BoolExpr::BoolExpr(const BoolExpr& l, NodeType t, const BoolExpr& r)
00268     : n(new Node) {
00269     unsigned int ls = ((l.n->t == t) || (l.n->t == NT_VAR)) ? l.n->same : 1;
00270     unsigned int rs = ((r.n->t == t) || (r.n->t == NT_VAR)) ? r.n->same : 1;
00271     n->same = ls+rs;
00272     n->t    = t;
00273     n->l    = l.n;
00274     n->l->use++;
00275     n->r    = r.n;
00276     n->r->use++;
00277   }
00278 
00279   BoolExpr::BoolExpr(const BoolExpr& l, NodeType t)
00280     : n(new Node) {
00281     (void) t;
00282     assert(t == NT_NOT);
00283     n->same = 1;
00284     n->t    = NT_NOT;
00285     n->l    = l.n;
00286     n->l->use++;
00287     n->r    = NULL;
00288   }
00289 
00290   BoolExpr::BoolExpr(const LinRel<IntVar>& rl)
00291     : n(new Node) {
00292     n->same   = 1;
00293     n->t      = NT_RLIN_INT;
00294     n->l      = NULL;
00295     n->r      = NULL;
00296     n->rl_int = rl;
00297   }
00298 
00299   BoolExpr::BoolExpr(const LinRel<BoolVar>& rl)
00300     : n(new Node) {
00301     n->same    = 1;
00302     n->t       = NT_RLIN_BOOL;
00303     n->l       = NULL;
00304     n->r       = NULL;
00305     n->rl_bool = rl;
00306   }
00307 
00308   const BoolExpr&
00309   BoolExpr::operator=(const BoolExpr& e) {
00310     if (this != &e) {
00311       if (n->decrement())
00312         delete n;
00313       n = e.n;
00314       n->use++;
00315     }
00316     return *this;
00317   }
00318 
00319   BoolExpr::~BoolExpr(void) {
00320     if (n->decrement())
00321       delete n;
00322   }
00323 
00324 
00325 }}
00326 
00327 // STATISTICS: minimodel-any